package logic

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"mall/common/cachex"
	"mall/service/product/model"
	"mall/service/product/rpc/internal/svc"
	"mall/service/product/rpc/types/product"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type DiagnoseLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewDiagnoseLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DiagnoseLogic {
	return &DiagnoseLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *DiagnoseLogic) Diagnose(in *product.DiagnoseReq) (*product.DiagnoseResp, error) {
	var count int
	var err error
	switch in.Diagnose {
	case 1: // 分析图片是否为残留记录（涉及到删除 分页要倒序，从最大值开始）
		count, err = l.diagnoseAttachment(in)
	case 2: // 分析图片有效性
		count, err = l.diagnoseAttachmentUrl(in)
	case 3: // 分析 product_detail
		count, err = l.diagnoseDetail(in)
	case 4: // 分析 product_meta
		count, err = l.diagnoseMetum(in)
	case 5: // 分析 product_term_relationships
		count, err = l.diagnoseTerm(in)
	case 6: // 分析 product_knowledge_base_relationships
		count, err = l.diagnoseRelationship(in)
	case 7: // 分析 product_meta  _thumbnail_id  _thumbnail_url
		count, err = l.diagnoseThumbnail(in)
	case 8: // 分析 product_variation_meta  _stock  _sold
		count, err = l.diagnoseStock(in)
	}

	if err != nil {
		return nil, err
	}

	return &product.DiagnoseResp{
		Total: int64(count),
	}, nil
}

func (l *DiagnoseLogic) diagnoseAttachment(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseAttachmentUrl(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseDetail(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseMetum(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseTerm(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseRelationship(in *product.DiagnoseReq) (count int, err error) {
	return
}

func (l *DiagnoseLogic) diagnoseThumbnail(in *product.DiagnoseReq) (count int, err error) {
	return
}

/**
 * _available int32 可用库存（实际库存减去已经锁定的库存）
 * _quantity  int32 实际库存
 */
func (l *DiagnoseLogic) diagnoseStock(in *product.DiagnoseReq) (count int, err error) {
	filterMap := make(map[string]map[string][]any)
	filterMap[model.ProductVariationMetumColumns.MetaKey] = map[string][]any{
		"in": []any{"_stock"},
	}

	list, _, err := l.svcCtx.Product.GetVariationMeta(l.ctx, model.M{
		"page":     in.Current,
		"pageSize": in.PageSize,
	}, -1, filterMap)
	if err != nil {
		return 0, err
	}

	if len(list) > 0 {
		for _, item := range list {
			key := strings.TrimSpace(item.MetaKey)
			if len(key) > 0 && item.MetaValue.Valid {
				val := strings.TrimSpace(item.MetaValue.String)

				if key == "_stock" && item.ProductID > 0 {
					if i, err := strconv.ParseInt(val, 10, 32); err == nil {
						stockKey := l.getStockKey(item.ProductID)
						err = l.svcCtx.BizRedis.SetCtx(l.ctx, stockKey, strconv.FormatInt(i, 10))
						if err != nil {
							logrus.Info(fmt.Sprintf("diagnoseStock SetCtx err: %+v", err))
						}

						stockFrozenKey := l.getStockFrozenKey(item.ProductID)
						_, err = l.svcCtx.BizRedis.SetnxCtx(l.ctx, stockFrozenKey, "0")
						if err != nil {
							logrus.Info(fmt.Sprintf("diagnoseStock SetnxCtx err: %+v", err))
						}
					}
				}
			}
		}
	}

	return
}

func (l *DiagnoseLogic) getStockKey(vid uint64) string {
	return fmt.Sprintf("{%s}:%d", cachex.SkuStock, vid)
}

func (l *DiagnoseLogic) getStockFrozenKey(vid uint64) string {
	return fmt.Sprintf("{%s}:%d:%s", cachex.SkuStock, vid, cachex.SkuStockFrozen)
}
